package com.ecarx.vhaltests.hy11.testcases.system.seatadjustment;

import static android.car.VehiclePropertyIds.SEAT_BACKREST_ANGLE_1_POS;

import android.car.VehicleAreaSeat;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.util.Log;

import com.ecarx.vhaltests.IpcpClient;
import com.ecarx.vhaltests.VehicleConstants;
import com.ecarx.vhaltests.VhalUnitTestBase;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

// 3.2.9 [SW_FC_004_046]第一排靠背调节1stRowSeatBackrestAdjustment
public class SeatBackrestAngle1PosTest extends VhalUnitTestBase {
    public static final String TAG = "SEAT_BACKREST_ANGLE_1_POS";
    private static int halValueRow1Left;
    private static int halStatusRow1Left;
    private static int halValueRow1Right;
    private static int halStatusRow1Right;
    final static Object lockRow1Left = new Object();
    final static Object lockRow1Right = new Object();


    private static final IpcpClient ipcpClient = new IpcpClient();

    @BeforeClass
    public static void testInit() {
        mCarPropertyMgr.registerCallback(carPropertyEventCallback, SEAT_BACKREST_ANGLE_1_POS, CarPropertyManager.SENSOR_RATE_ONCHANGE);
        setConfig();
    }

    @Test
    public void testBackrestAngle1PosNotAvail() {
        setBackrestAngle1PosNotAvail();
        lockRow1Left();
        lockRow1Right();
        Assert.assertEquals(halStatusRow1Left, 1);
        Assert.assertEquals(halStatusRow1Right, 1);
        testBackrestAngle1PosNotAvailLeft();
        testBackrestAngle1PosNotAvailRight();
    }

    @Test
    public void testBackrestAngle1PosAvail() {
        setBackrestAngle1PosAvail();
        lockRow1Left();
        lockRow1Right();
        Assert.assertEquals(halStatusRow1Left, 0);
        Assert.assertEquals(halStatusRow1Right, 0);
        testBackrestAngle1PosIsAvailLeft();
        testBackrestAngle1PosIsAvailRight();
    }


    @Test
    public void testSeatHeightMoveRow1Left100() {
        setBackrestAngle1PosAvail();
        setCDMDriver(100);
        lockRow1Left();
        Assert.assertEquals(halValueRow1Left, 100);
        Assert.assertEquals(halStatusRow1Left, 0);
        testBackrestAngle1PosValue(VehicleAreaSeat.SEAT_ROW_1_LEFT, 100);
    }

    @Test
    public void testSeatHeightMoveRow1LeftLimit() {//超过限制返回上次的值
        setBackrestAngle1PosAvail();
        setCDMDriver(120);
        lockRow1Left();
        Assert.assertEquals(halValueRow1Left, 120);
        Assert.assertEquals(halStatusRow1Left, 0);
        testBackrestAngle1PosValue(VehicleAreaSeat.SEAT_ROW_1_LEFT, 120);

        setCDMDriver(50);
        lockRow1Left();
        Assert.assertEquals(halValueRow1Left, 120);
        testBackrestAngle1PosValue(VehicleAreaSeat.SEAT_ROW_1_LEFT, 120);
    }

    @Test
    public void testSeatHeightMoveRow1Right100() {
        setBackrestAngle1PosAvail();
        setCDMPass(100);
        lockRow1Left();
        Assert.assertEquals(halValueRow1Right, 100);
        Assert.assertEquals(halStatusRow1Right, 0);
        testBackrestAngle1PosValue(VehicleAreaSeat.SEAT_ROW_1_RIGHT, 100);
    }

    @Test
    public void testSeatHeightMoveRow1Right50Limit() {//超过限制返回上次的值
        setBackrestAngle1PosAvail();
        setCDMPass(130);
        lockRow1Left();
        Assert.assertEquals(halValueRow1Right, 130);
        Assert.assertEquals(halStatusRow1Right, 0);
        testBackrestAngle1PosValue(VehicleAreaSeat.SEAT_ROW_1_RIGHT, 130);

        setCDMPass(180);
        lockRow1Left();
        Assert.assertEquals(halValueRow1Right, 130);
        testBackrestAngle1PosValue(VehicleAreaSeat.SEAT_ROW_1_RIGHT, 130);
    }

    public void testBackrestAngle1PosValue(int areaId, int value) {
        int halValue = mCarPropertyMgr.getIntProperty(SEAT_BACKREST_ANGLE_1_POS, areaId);
        Assert.assertEquals(halValue, value);
    }

    public void testBackrestAngle1PosIsAvailLeft() {
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(SEAT_BACKREST_ANGLE_1_POS, VehicleAreaSeat.SEAT_ROW_1_LEFT);
        Assert.assertTrue(isAvail);
    }

    public void testBackrestAngle1PosIsAvailRight() {
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(SEAT_BACKREST_ANGLE_1_POS, VehicleAreaSeat.SEAT_ROW_1_RIGHT);
        Assert.assertTrue(isAvail);
    }

    public void testBackrestAngle1PosNotAvailLeft() {
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(SEAT_BACKREST_ANGLE_1_POS, VehicleAreaSeat.SEAT_ROW_1_LEFT);
        Assert.assertFalse(isAvail);
    }

    public void testBackrestAngle1PosNotAvailRight() {
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(SEAT_BACKREST_ANGLE_1_POS, VehicleAreaSeat.SEAT_ROW_1_RIGHT);
        Assert.assertFalse(isAvail);
    }

    public void lockRow1Left() {
        try {
            synchronized (lockRow1Left) {
                lockRow1Left.wait(1000);
            }

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void lockRow1Right() {
        try {
            synchronized (lockRow1Right) {
                lockRow1Right.wait(1000);
            }

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static final CarPropertyManager.CarPropertyEventCallback carPropertyEventCallback = new CarPropertyManager.CarPropertyEventCallback() {
        @Override
        public void onChangeEvent(CarPropertyValue carPropertyValue) {
            try {
                Log.d(TAG, carPropertyValue.toString());

                int areaId = carPropertyValue.getAreaId();
                if (areaId == VehicleAreaSeat.SEAT_ROW_1_LEFT) {
                    halValueRow1Left = (int) carPropertyValue.getValue();
                    halStatusRow1Left = carPropertyValue.getStatus();
                    synchronized (lockRow1Left) {
                        lockRow1Left.notify();
                    }
                } else if (areaId == VehicleAreaSeat.SEAT_ROW_1_RIGHT) {
                    halValueRow1Right = (int) carPropertyValue.getValue();
                    halStatusRow1Right = carPropertyValue.getStatus();
                    synchronized (lockRow1Right) {
                        lockRow1Right.notify();
                    }
                }
            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
        }

        @Override
        public void onErrorEvent(int i, int i1) {

        }
    };

    private static void setConfig() {

        int ccSvcId = 135;
        int[] ccOperIds = {200};
        int cc1000SvcId = 136;
        int[] cc1000OperIds = {200};
        int cdmSvcId = 36;
        int[] cdmOperIds = {999};

        boolean retCc = ipcpClient.setConfig(ccSvcId, ccOperIds);
        Assert.assertTrue(retCc);

        boolean retCdm = ipcpClient.setConfig(cdmSvcId, cdmOperIds);
        Assert.assertTrue(retCdm);

        boolean retCc1000 = ipcpClient.setConfig(cc1000SvcId, cc1000OperIds);
        Assert.assertTrue(retCc1000);

    }

    public void setBackrestAngle1PosNotAvail() {
        setCarConfig(6, 5);
        setCarConfig1000(3, 6);
    }


    public void setBackrestAngle1PosAvail() {
        setCarConfig(4, 2);
        setCarConfig1000(2, 2);
        setCDM(110,110);
    }


    public void setCarConfig(int cc184, int cc471) {
        int ccSvcId = 135;
        int ccOperId = 200;
        int[] configs = {184, 471};
        int[] values = {cc184, cc471};
        boolean ccResult = ipcpClient.setCarconfigSignal(ccSvcId, ccOperId, configs, values);
        Assert.assertTrue(ccResult);
        delay();
    }

    private void setCarConfig1000(int cc1173, int cc1174) {
        int ccSvcId = 136;
        int ccOperId = 200;
        int[] configs = {1173, 1174};
        int[] values = {cc1173, cc1174};
        boolean ccResult = ipcpClient.setCarconfig1000Signal(ccSvcId, ccOperId, configs, values);
        Assert.assertTrue(ccResult);
        delay();
    }

    public void setCDMDriver(int seatBackAngleRowFirstDrvr) {
        setCDM(seatBackAngleRowFirstDrvr, 0);
    }

    public void setCDMPass(int seatBackAngleRowFirstPass) {
        setCDM(0, seatBackAngleRowFirstPass);
    }

    public void setCDM(int seatBackAngleRowFirstDrvr, int seatBackAngleRowFirstPass) {
        int cdmSvcId = 36;
        int cdmOperId = 999;
        String[] cdms = {"seatBackAngleRowFirstDrvr", "seatBackAngleRowFirstPass"};
        int[] cdmValues = {seatBackAngleRowFirstDrvr, seatBackAngleRowFirstPass };
        boolean cdmResult = ipcpClient.setCDMSignal(cdmSvcId, cdmOperId, cdms, cdmValues);
        Assert.assertTrue(cdmResult);
        delay();
    }

}